function [success, errorMsg] = RequirementsTreeManager(action, varargin)
    % RequirementsTreeManager - 需求文件树管理器
    % 负责构建和管理DO_02_Requirements文件夹下的slreqx文件树
    %
    % 输入参数:
    %   action - 操作类型: 'buildTree', 'openFile'
    %   varargin - 根据操作类型的附加参数
    %
    % 输出参数:
    %   success - 逻辑值，true表示成功，false表示失败
    %   errorMsg - 字符串，错误信息（成功时为空）
    %
    % 使用示例:
    %   % 构建树结构
    %   [success, errorMsg] = RequirementsTreeManager('buildTree', treeComponent, projectRoot);
    %   
    %   % 打开文件
    %   [success, errorMsg] = RequirementsTreeManager('openFile', filePath);
    %
    % 作者: MBD Platform
    % 日期: 2025-09-14
    % 版本: 1.0

    success = false;
    errorMsg = '';
    
    try
        switch lower(action)
            case 'buildtree'
                [success, errorMsg] = buildRequirementsTree(varargin{:});
            case 'openfile'
                [success, errorMsg] = openSlreqxFile(varargin{:});
            case 'refreshtree'
                [success, errorMsg] = refreshRequirementsTree(varargin{:});
            otherwise
                errorMsg = sprintf('未知操作类型: %s', action);
        end
    catch ME
        errorMsg = sprintf('需求文件树管理器错误: %s', ME.message);
    end
end

function [success, errorMsg] = buildRequirementsTree(treeComponent, projectRoot)
    % 构建需求文件树
    % 输入: treeComponent - 树控件, projectRoot - 项目根目录
    % 输出: success - 成功标志, errorMsg - 错误信息
    
    success = false;
    errorMsg = '';
    
    try
        % 清空现有树结构
        delete(treeComponent.Children);
        
        % DO_02_Requirements文件夹路径
        reqFolder = fullfile(projectRoot, 'DO_02_Requirements');
        
        if ~exist(reqFolder, 'dir')
            errorMsg = sprintf('需求文件夹不存在: %s', reqFolder);
            return;
        end
        
        % 创建根节点
        rootNode = uitreenode(treeComponent);
        rootNode.Text = 'DO_02_Requirements';
        rootNode.UserData = struct('Type', 'folder', 'Path', reqFolder);
        
        % 递归扫描文件夹，只显示slreqx文件
        scanFolder(rootNode, reqFolder);
        
        % 展开根节点
        expand(rootNode);
        
        success = true;
        
    catch ME
        errorMsg = sprintf('构建需求文件树失败: %s', ME.message);
    end
end

function scanFolder(parentNode, folderPath)
    % 递归扫描文件夹，构建树结构
    % 输入: parentNode - 父节点, folderPath - 文件夹路径
    
    try
        % 获取文件夹内容
        dirContents = dir(folderPath);
        
        % 首先处理子文件夹
        for i = 1:length(dirContents)
            item = dirContents(i);
            
            % 跳过特殊目录
            if strcmp(item.name, '.') || strcmp(item.name, '..')
                continue;
            end
            
            itemPath = fullfile(folderPath, item.name);
            
            if item.isdir
                % 创建文件夹节点
                folderNode = uitreenode(parentNode);
                folderNode.Text = item.name;
                folderNode.UserData = struct('Type', 'folder', 'Path', itemPath);
                
                % 递归扫描子文件夹
                scanFolder(folderNode, itemPath);
                
                % 如果子文件夹没有slreqx文件，删除此节点
                if isempty(folderNode.Children)
                    delete(folderNode);
                end
            end
        end
        
        % 然后处理slreqx文件
        for i = 1:length(dirContents)
            item = dirContents(i);
            
            if ~item.isdir
                [~, ~, ext] = fileparts(item.name);
                
                if strcmpi(ext, '.slreqx')
                    % 创建slreqx文件节点
                    fileNode = uitreenode(parentNode);
                    fileNode.Text = item.name;
                    fileNode.UserData = struct('Type', 'slreqx', 'Path', fullfile(folderPath, item.name));
                    
                    % 添加文件信息到工具提示
                    try
                        fileInfo = dir(fullfile(folderPath, item.name));
                        if ~isempty(fileInfo)
                            fileNode.Tooltip = sprintf('文件: %s\n大小: %.2f KB\n修改时间: %s', ...
                                item.name, fileInfo(1).bytes/1024, datestr(fileInfo(1).datenum));
                        end
                    catch
                        % 工具提示创建失败时静默处理
                    end
                end
            end
        end
        
    catch ME
        % 显示错误信息但不中断程序执行
        fprintf('扫描文件夹 %s 时出错: %s\n', folderPath, ME.message);
    end
end

function [success, errorMsg] = refreshRequirementsTree(treeComponent, projectRoot)
    % 刷新需求文件树
    % 输入: treeComponent - 树控件, projectRoot - 项目根目录
    % 输出: success - 成功标志, errorMsg - 错误信息
    
    % 刷新就是重新构建树
    [success, errorMsg] = buildRequirementsTree(treeComponent, projectRoot);
end

function [success, errorMsg] = openSlreqxFile(filePath)
    % 打开slreqx文件
    % 输入: filePath - 文件路径
    % 输出: success - 成功标志, errorMsg - 错误信息
    
    success = false;
    errorMsg = '';
    
    try
        if ~exist(filePath, 'file')
            errorMsg = sprintf('文件不存在: %s', filePath);
            return;
        end
        
        [~, ~, ext] = fileparts(filePath);
        if ~strcmpi(ext, '.slreqx')
            errorMsg = sprintf('不是有效的slreqx文件: %s', filePath);
            return;
        end
        
        % 使用MATLAB的slreq.open函数打开slreqx文件
        try
            % 检查Simulink Requirements工具箱是否可用
            if license('test', 'Simulink_Requirements')
                slreq.open(filePath);
                success = true;
            else
                % 如果没有许可证，尝试用系统默认程序打开
                if ispc
                    system(['start "" "' filePath '"']);
                elseif ismac
                    system(['open "' filePath '"']);
                else
                    system(['xdg-open "' filePath '"']);
                end
                success = true;
            end
        catch slreqError
            % 如果slreq.open失败，尝试系统默认程序
            if ispc
                [status, ~] = system(['start "" "' filePath '"']);
            elseif ismac
                [status, ~] = system(['open "' filePath '"']);
            else
                [status, ~] = system(['xdg-open "' filePath '"']);
            end
            
            if status == 0
                success = true;
            else
                errorMsg = sprintf('无法打开文件: %s\n原始错误: %s', filePath, slreqError.message);
            end
        end
        
    catch ME
        errorMsg = sprintf('打开slreqx文件时出错: %s', ME.message);
    end
end
